#pragma once

#include "IBoundary2.h"
#include "IDomain2.h"

class ILinearEdge2;
class IStackAllocator;

/**@warning not exception safe*/
class ConvolutionExImEdge2 : public IEdge2
{
public:
	ConvolutionExImEdge2(
		const ILinearEdge2& edgeA, const Vector2& tA, 
		const IImplicitBounded2& domainB, const Vector2& tB,
		IStackAllocator& stack);
	~ConvolutionExImEdge2();

	virtual const Vector2 startPoint() const;
	virtual const Vector2 endPoint() const;
	virtual const Vector2 startNormal() const;
	virtual const Vector2 endNormal() const;

	virtual IVertexIterator2* segmentate(Scalar tolerance, IStackAllocator& stack) const;

private:
	const ILinearEdge2* edgeA_;
	Vector2 tA_;
	const IImplicitBounded2* domainB_;
	Vector2 tB_;
	IStackAllocator* stack_;	
};

/// convolution of boundary of IExplicitBounded2 A and boundary of IImplicitBounded2 B
/** first, get an edge while traverse A,
 *  then traverse a part of B in normal range of the edge of A. */
class ConvolutionExIm2 : public IEdgeIterator2
{
public:
	ConvolutionExIm2(
		const IExplicitBounded2& domainA, const Vector2& tA,
		const IImplicitBounded2& domainB, const Vector2& tB,
		IStackAllocator& stack);
	virtual ~ConvolutionExIm2();

	virtual const IEdge2& current() const;
	virtual bool next();

private:
	ConvolutionExImEdge2* createCurrentEdge();

private:
	ILinearEdgeIterator2* boundaryA_;
	Vector2 tA_;
	const IImplicitBounded2* domainB_;
	Vector2 tB_;
	IStackAllocator* stack_;
	ConvolutionExImEdge2* currentEdge_;
};
